﻿Module Configuration

    ''' <summary>
    ''' Generic Structure to handle the entire Application Configuration
    ''' </summary>
    ''' <remarks></remarks>
    Public Structure ApplicationConfiguration
        Public JumpToShell As Boolean
        Public InputFilename As List(Of String)
        Public OutputFilename As String
        Public OutputProtocol As String
        Public PrintHelpOnly As Boolean
        Public Verbose As Boolean
        Public PackageDescription As String
        Public Flags As Dictionary(Of String, String)
        Public ShadowMode As Boolean
        Public ShadowDeleteEntries As List(Of String)
    End Structure
    Public LastErrorCode As SupportedExitCodes
    Public Enum SupportedExitCodes As Integer
        CompilationSucceeded = 0
        ioCantOpenSourceFile = 1
        ioCantOpenDestinationFile = 2
        ioSourceFileEmpty = 3
        NoSourceFiles = 4
        NoTargetFile = 5
        InvalidPackageFlags = 6
        InsuficientFreeSpace = 7
        SimulationException = 8
        CompilationAborted = 9
        Reserved0 = 10
        Reserved1 = 11
        Reserved2 = 12
        Reserved3 = 13
        Reserved4 = 14
        CompilerException = 15

        ' Application specific codes
        NoTaskSpecified
        ShellDrop
        NoCompilerFound


    End Enum
    'Public Enum SupportedExitCodesCollection As Integer
    '    ' 0 Normal Execution
    '    ' 1-64 Application parameters and configuration errors
    '    ' 65-89 Exceptions
    '    ' 90-127 RESERVED
    '    '128-4224 SIM: Invalid Source File: (exitCode - 128)
    '    '4225-8321 COMPILER: Invalid Source File: (exitcode - 4225)

    '    NormalExecution = 0

    '    '1-64
    '    InteractiveShellDrop = 1
    '    NoInputFilesSpecified = 2
    '    NoOutputFileSpecified = 3
    '    NoProtocolSpecified = 4
    '    ProtocolNotSupported = 5

    '    '65-89
    '    CantOpenOutputFile = 65
    '    InsufficientDiskSpace = 66
    '    CompilationExceedsCompilerLimits = 67
    '    UnhandledCompilerException = 68

    '    '90-127
    '    Reserved1 = 90

    '    '128-4224
    '    InvalidSourceFileSimFlag = 128

    '    '4225-8321
    '    InvalidSourceFileCompilerFlag = 4225
    'End Enum

    Public CurrentConfiguration As ApplicationConfiguration
    Public DefaultConfiguration As ApplicationConfiguration

    ''' <summary>
    ''' Initializes the Application with the Default configuration
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub InitializeDefaultConfiguration()
        With DefaultConfiguration
            .InputFilename = Nothing
            .JumpToShell = True
            .OutputFilename = ""
            .OutputProtocol = ""
            .PrintHelpOnly = False
            .Verbose = False
            .PackageDescription = ""
            .Flags = New Dictionary(Of String, String)(32)
            .ShadowMode = False
            .ShadowDeleteEntries = New List(Of String)()
            .InputFilename = New List(Of String)(4096)
        End With

        CurrentConfiguration = DefaultConfiguration

        If Platform = PlatformName.Windows Then
            Try
                ' Try to increment the Console buffer and window height (if its 80 or less only)
                If Console.BufferWidth <= 80 Then
                    Console.BufferWidth = 100
                End If
                If Console.WindowWidth <= 80 Then
                    Console.WindowWidth = 100
                End If
            Catch
                ' Ignore
            End Try
        End If

        Try
            ' Try to set the Console Title
            Dim myProcess As Process
            myProcess = Process.GetCurrentProcess
            Console.Title = "ACU - PID:" & myProcess.Id
            myProcess.Dispose()
        Catch
            ' Ignore
        End Try

        ' Initialize Compilers / ADD HERE THE NEW COMPILERS
        ReDim AvailableCompilers(2)
        AvailableCompilers(0) = New Compilers.DeveloperDebugCompiler
        AvailableCompilers(1) = New Compilers.X1010_Compiler
        AvailableCompilers(2) = New Compilers.X1020_Compiler
    End Sub

    Public AvailableCompilers() As Compilers.GenericCompiler
    'Public LastErrorCode As SupportedExitCodesCollection

    ' FLAG SUPPORT
    Public Sub SetFlag(ByVal flag As String, ByVal value As String)
        ' Returns true if succeeds, otherwise false

        flag = Trim(LCase(flag))
        value = Trim(value)

        If (CurrentConfiguration.Flags.Count > 0) AndAlso (CurrentConfiguration.Flags.ContainsKey(flag)) Then
            AddLogV("Previous value for flag <" & flag & "> is <" & CurrentConfiguration.Flags(flag) & ">")
            AddLog("Updated flag <" & flag & ">: " & value)
            CurrentConfiguration.Flags(flag) = value
        Else
            AddLog("Added flag <" & flag & ">: " & value)
            CurrentConfiguration.Flags.Add(flag, value)
        End If

    End Sub
    Public Function GetFlag(ByVal flag As String, ByVal defaultValue As String) As String
        ' Returns an specified flag. If it doesnt exists, returns defaultValue

        flag = Trim(LCase(flag))

        If (CurrentConfiguration.Flags.Count > 0) AndAlso (CurrentConfiguration.Flags.ContainsKey(flag)) Then
            Return CurrentConfiguration.Flags(flag)
        Else
            Return defaultValue
        End If
    End Function
    Public Function HasFlag(ByVal flag As String) As Boolean
        ' Returns if a Flag exists or not

        flag = Trim(LCase(flag))

        Return ((CurrentConfiguration.Flags.Count > 0) AndAlso (CurrentConfiguration.Flags.ContainsKey(flag)))
    End Function
    Public Function GetFlags() As System.Collections.Generic.KeyValuePair(Of String, String)()
        ' Gets all flags specified for the current compiler

        Dim output(CurrentConfiguration.Flags.Count - 1) As KeyValuePair(Of String, String)
        Dim i As Integer

        For Each x In CurrentConfiguration.Flags
            output(i) = x
            i = i + 1
        Next

        Return output
    End Function
    Public Sub RemoveFlag(ByVal flag As String)
        ' Removes an specified flag if exists

        flag = Trim(LCase(flag))

        If CurrentConfiguration.Flags.ContainsKey(flag) Then
            CurrentConfiguration.Flags.Remove(flag)
            AddLog("Flag <" & flag & "> was removed from store.")
        Else
            AddLogV("Warning: Flag <" & flag & "> dont exists.")
        End If
    End Sub
End Module
